package com.cnswhy.cloud.common.rabbitmq.configure;

import com.cnswhy.cloud.common.rabbitmq.constant.DLXMQConstant;
import com.cnswhy.cloud.common.rabbitmq.constant.MQConstant;
import com.cnswhy.cloud.common.rabbitmq.properties.CnswhyRabbitmqProperties;
import com.cnswhy.cloud.common.rabbitmq.service.MessageService;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import java.util.HashMap;
import java.util.Map;


/**
 * Lettuce Redis配置
 *
 * @author cnswhy
 */
@EnableConfigurationProperties(CnswhyRabbitmqProperties.class)
//@ConditionalOnProperty(prefix =  CnswhyRabbitmqProperties.PREFIX , name = "enable", havingValue = "true", matchIfMissing = false)
public class CnswhyRabbitmqConfigure {
    private final CnswhyRabbitmqProperties cnswhyRabbitmqProperties;

    public CnswhyRabbitmqConfigure(CnswhyRabbitmqProperties properties){
        this.cnswhyRabbitmqProperties = properties;
    }

    @Bean
    @ConditionalOnProperty(prefix =  CnswhyRabbitmqProperties.PREFIX , name = "enable", havingValue = "true")
    public CachingConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(cnswhyRabbitmqProperties.getHost(), cnswhyRabbitmqProperties.getPort());
        connectionFactory.setUsername(cnswhyRabbitmqProperties.getUsername());
        connectionFactory.setPassword(cnswhyRabbitmqProperties.getPassword());
        connectionFactory.setVirtualHost(cnswhyRabbitmqProperties.getVirtualHost());
        //connectionFactory.setPublisherConfirms(true);
        connectionFactory.setPublisherConfirms(true);
        return connectionFactory;
    }

    @Bean
    @ConditionalOnProperty(prefix =  CnswhyRabbitmqProperties.PREFIX , name = "enable", havingValue = "true")
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        /*template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if(!ack){
                    logger.info("send message failed: " + cause);
                    throw new RuntimeException("send error " + cause);
                }
            }
        });*/
        return template;
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public MessageService messageService() {
        return new MessageService();
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public DirectExchange defaultExchange() {
        return new DirectExchange(MQConstant.DEFAULT_EXCHANGE, true, false);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue repeatTradeQueue() {
        return new Queue(MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME, true, false, false);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding drepeatTradeBinding() {
        return BindingBuilder.bind(repeatTradeQueue()).to(defaultExchange()).with(MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(MQConstant.DEFAULT_DEAD_LETTER_QUEUE_NAME, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding() {
        return BindingBuilder.bind(deadLetterQueue()).to(defaultExchange()).with(MQConstant.DEFAULT_DEAD_LETTER_QUEUE_NAME);
    }

    /*需要绑定死信队列*/
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue paybankOrderQueryQueue() {
        return new Queue(MQConstant.PAYBANK_QUERY_QUEUE);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue collectpayOrderQueryQueue() {
        return new Queue(MQConstant.COLLECTPAY_QUERY_QUEUE);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue colletpayOrderSubmitQueue() {
        return new Queue(MQConstant.COLLECTPAY_SUBMIT_QUEUE);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue paybankOrderSubmitQueue() {
        return new Queue(MQConstant.PAYBANK_SUBMIT_QUEUE);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue transQueryQueue() {
        return new Queue(MQConstant.TRANS_QUERY_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue transNotifyQueue() {
        return new Queue(MQConstant.TRANS_NOTIFY_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue smsQueue() {
        return new Queue(MQConstant.SMS_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue splitQueue() {
        return new Queue(MQConstant.SPLIT_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue upgradeSplitQueue() {
        return new Queue(MQConstant.UPGRADE_SPLIT_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue aliMonitorQueue() {
        return new Queue(MQConstant.ALI_MONITOR_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue settleQueue() {
        return new Queue(MQConstant.SETTLE_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue transSettleRptQueue() {
        return new Queue(MQConstant.TRANS_SETTLE_RPT_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue transSettleRptAddReportQueue() {
        return new Queue(MQConstant.TRANS_SETTLE_RPT_ADD_REPORT_QUEUE);
    }


    //cnswhy

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue withdrawFailureQueue() {
        return new Queue(MQConstant.WITHDRAW_FAILURE_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue withdrawSuccessQueue() {
        return new Queue(MQConstant.WITHDRAW_SUCCESS_QUEUE);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue resetCustomerSpellStatusQueue() {
        return new Queue(MQConstant.RESET_CUSTOMER_SPELL_STATUS_QUEUE);
    }
    //end cnswhy
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue10() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_10, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding10() {
        return BindingBuilder.bind(deadLetterQueue10()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_10);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue20() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_20, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding20() {
        return BindingBuilder.bind(deadLetterQueue20()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_20);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue40() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_40, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding40() {
        return BindingBuilder.bind(deadLetterQueue40()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_40);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue80() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_80, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding80() {
        return BindingBuilder.bind(deadLetterQueue80()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_80);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue160() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_160, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding160() {
        return BindingBuilder.bind(deadLetterQueue160()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_160);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue320() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_320, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding320() {
        return BindingBuilder.bind(deadLetterQueue320()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_320);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue640() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_640, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding640() {
        return BindingBuilder.bind(deadLetterQueue640()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_640);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue1280() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_1280, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding1280() {
        return BindingBuilder.bind(deadLetterQueue1280()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_1280);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue2560() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_2560, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding2560() {
        return BindingBuilder.bind(deadLetterQueue2560()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_2560);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue5120() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_5120, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding5120() {
        return BindingBuilder.bind(deadLetterQueue5120()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_5120);
    }
    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Queue deadLetterQueue10240() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", MQConstant.DEFAULT_EXCHANGE);
        arguments.put("x-dead-letter-routing-key", MQConstant.DEFAULT_REPEAT_TRADE_QUEUE_NAME);
        return new Queue(DLXMQConstant.DEAD_LETTER_QUEUE_10240, true, false, false, arguments);
    }

    @Bean
    @ConditionalOnBean(name = "rabbitTemplate")
    public Binding deadLetterBinding10240() {
        return BindingBuilder.bind(deadLetterQueue10240()).to(defaultExchange()).with(DLXMQConstant.DEAD_LETTER_QUEUE_10240);
    }
}